﻿// -----------------------------------------------------------------------
// <copyright file="SPExportCmdlet.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace SPMigrationCmdlets
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Management.Automation;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Xml;
    using SharePoint.ImportExport.Core;
    using System.Data;
    using Sharepoint.ImportExport.Extractor;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    [Cmdlet(VerbsData.Export, "SPMigrationData")]
    public class Exporter : PSCmdlet
    {
                /// <summary>
        /// This is a date threshold
        /// </summary>
        private DateTime exportItemsOlderThan = DateTime.MinValue;

        /// <summary>
        /// This is a date threshold
        /// </summary>
        private DateTime exportItemsNewerThan;

        /// <summary>
        /// This is a boolean flag controlling if .aspx pages are exported
        /// </summary>
        private bool exportDesign = false;

        /// <summary>
        /// This is a boolean flag controlling if versions are exported
        /// </summary>
        private bool exportVersions = true;

        /// <summary>
        /// This is a boolean flag controlling if content from sub sites will be exported
        /// </summary>
        private bool includeSubWebs = true;

        /// <summary>
        /// This is the name of the directory that will contain the exported data
        /// </summary>
        private string directoryName;

        /// <summary>
        /// This is the URL to the site to be exported
        /// </summary>
        private string siteURL;

        /// <summary>
        /// This is a boolean flag controlling if user information will be exported
        /// </summary>
        private bool exportUserInfo = true;

        /// <summary>
        /// This is a boolean flag controlling if views will be exported
        /// </summary>
        private bool exportViews = true;

        /// <summary>
        /// If set only this list will be exported
        /// </summary>
        private string list;

        /// <summary>
        /// If set only this folder will be exported
        /// </summary>
        private string folder = String.Empty;

        /// <summary>
        /// Boolean flag indicating whether or not the data should be compressed
        /// </summary>
        private bool compress;

        /// <summary>
        /// Gets or sets the URL to the SharePoint site to be exported
        /// </summary>
        [Parameter(Position = 0, Mandatory = true)]
        public string SiteURL
        {
            get
            {
                return this.siteURL;
            }

            set
            {
                this.siteURL = value;
            }
        }

        /// <summary>
        /// Gets or sets the output directory
        /// </summary>
        [Parameter(Position = 1, Mandatory = true)]
        public string DirectoryName
        {
            get
            {
                return this.directoryName;
            }

            set
            {
                this.directoryName = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether subwebs should be processed
        /// </summary>
        [Parameter(Position = 2, Mandatory = false)]
        public bool IncludeSubSites
        {
            get
            {
                return this.includeSubWebs;
            }

            set
            {
                this.includeSubWebs = value;
            }
        }
        /// <summary>
        /// Gets or sets the optional list parameter
        /// </summary>
        [Parameter(Position = 3, Mandatory = false)]
        public string List
        {
            get
            {
                return this.list;
            }

            set
            {
                this.list = value;
            }
        }

        /// <summary>
        /// Gets or sets the optional Folder that will be extracted
        /// </summary>
        [Parameter(Position = 4, Mandatory = false)]
        public string Folder
        {
            get
            {
                return this.folder;
            }
            
            set
            {
                this.folder = value;
            }
        }

        /// <summary>
        /// Gets or sets the time threshold. If set only items newer than the threshold will be exported
        /// </summary>
        [Parameter(Position = 5, Mandatory = false)]
        public DateTime ExportItemsNewerThan
        {
            get
            {
                return this.exportItemsNewerThan;
            }
            
            set
            {
                this.exportItemsNewerThan = value;
            }
        }

        /// <summary>
        /// Gets or sets the time threshold. If set only items older than the threshold will be exported
        /// </summary>
        [Parameter(Position = 6, Mandatory = false)]
        public DateTime ExportItemsOlderThan
        {
            get
            {
                return this.exportItemsOlderThan;
            }

            set
            {
                this.exportItemsOlderThan = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether user data will be extracted
        /// </summary>
        [Parameter(Position = 7, Mandatory = false)]
        public bool ExportUserInfo
        {
            get
            {
                return this.exportUserInfo;
            }

            set
            {
                this.exportUserInfo = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether versions should be processed
        /// </summary>
        [Parameter(Position = 8, Mandatory = false)]
        public bool ExportVersions
        {
            get
            {
                return this.exportVersions;
            }

            set
            {
                this.exportVersions = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether design elements should be processed
        /// </summary>
        [Parameter(Position = 9, Mandatory = false)]
        public bool ExtractDesignElements
        {
            get
            {
                return this.exportDesign;
            }

            set
            {
                this.exportDesign = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether or not the data should be compressed
        /// </summary>
        [Parameter(Position = 10, Mandatory = false)]
        public bool ExportViews
        {
            get
            {
                return this.exportViews;
            }
            set
            {
                this.exportViews = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether or not the data should be compressed
        /// </summary>
        [Parameter(Position = 11, Mandatory = false)]
        public bool Compress
        {
            get
            {
                return this.compress;
            }
            set
            {
                this.compress = value;
            }
        }



        protected override void ProcessRecord()
        {

#if  DEBUG
            System.Diagnostics.Debug.Assert(false);
#endif
            Sharepoint.ImportExport.Extractor.Exporter extractor = new Sharepoint.ImportExport.Extractor.Exporter();
            DataSet ds = new DataSet("Export Parameters");
            DataTable dt = ds.Tables.Add("Parameters");

            dt.Columns.Add("SiteURL");
            dt.Columns.Add("OutputDirectory");
            dt.Columns.Add("SiteName");
            dt.Columns.Add("List");
            dt.Columns.Add("Owner");
            dt.Columns.Add("Contact");
            dt.Columns.Add("IncludeSubWebs", typeof(bool));
            dt.Columns.Add("ManagedPath");
            dt.Columns.Add("SiteDef");
            dt.Columns.Add("Folder");
            dt.Columns.Add("ExportItemsNewerThan", typeof(System.DateTime));
            dt.Columns.Add("ExportItemsOlderThan", typeof(System.DateTime));
            dt.Columns.Add("ExportDesign", typeof(bool));
            dt.Columns.Add("ExportUsers", typeof(bool));
            dt.Columns.Add("ExportVersions", typeof(bool));
            dt.Columns.Add("ExportDoclibsOnly", typeof(bool));
            dt.Columns.Add("ProcessGalleries", typeof(bool));
            dt.Columns.Add("ExportViews", typeof(bool));

            DataRow newRow = dt.NewRow();

            // Set values in the columns:
            newRow["SiteURL"] = SiteURL;
            newRow["OutputDirectory"] = DirectoryName;
            newRow["SiteName"] = String.Empty;
            newRow["List"] = List;
            newRow["Owner"] = String.Empty;
            newRow["Contact"] = String.Empty;
            newRow["IncludeSubWebs"] = IncludeSubSites;
            newRow["ManagedPath"] = String.Empty;
            newRow["Folder"] = Folder;
            newRow["ExportItemsNewerThan"] = ExportItemsNewerThan;
            newRow["ExportDesign"] = ExtractDesignElements;
            newRow["ExportUsers"] = ExportUserInfo;
            newRow["ExportItemsOlderThan"] = ExportItemsOlderThan;
            newRow["ExportVersions"] = ExportVersions;
            newRow["ExportDoclibsOnly"] = false;
            newRow["ProcessGalleries"] = false;
            newRow["ExportViews"] = ExportViews;

            // Add the row to the rows collection.
            dt.Rows.Add(newRow);
            Logger.Init(DirectoryName + "\\export" + DateTime.Now.ToString("MMddHHmm") + ".log", ErrorLevel.Information);
            WriteVerbose("Log file: " + DirectoryName + "\\export" + DateTime.Now.ToString("MMddHHmm") + ".log");
           
            
            try
            {
                Logger.LogDataSendingEvent += new Logger.LogDataEventHandler(IncomingEventLogData);

                extractor.Process(ds);

                Logger.LogDataSendingEvent -= new Logger.LogDataEventHandler(IncomingEventLogData);
            }
            catch (Exception Ex)
            {
                Console.WriteLine("Exception occurred :" + Ex.Message);
            }

            try
            {
                Logger.Close();
            }
            catch (Exception Ex)
            {
            }

        }
        private void IncomingEventLogData(object sender, SPEventArgs e)
        {
            string message = e.Message;
            if (message.Contains("Warning-"))
            {
                message = message.Replace("Warning-", "");
                WriteWarning(message);
            }
            else if (message.Contains("Error-"))
            {
                message = message.Replace("Error-", "");
                ErrorRecord er = new ErrorRecord(new Exception(message.Replace("Error-", "")), "SPMIGER001", ErrorCategory.InvalidOperation, null);
                WriteError(er);
                return;
            }
            else
            {
                message = message.Replace("Information-", "");
                message = message.Replace("Progress-", "");
                string logArgs = DateTime.Now.ToLongTimeString() + "  " + message;
                WriteVerbose(logArgs);
                WriteCommandDetail(logArgs);
            }
        }
    }
}
